#include <QDebug>
#include <QStringBuilder>
#include <QRegExp>
#include <QDir>
#include <QTimer>
#include "Console.h"

Console::Console(QWidget *parent) :
    QTextBrowser(parent),
    _timer(new QTimer(this))
{
    setOpenLinks(false);
    connect(this, SIGNAL(anchorClicked(QUrl)), SLOT(onAnchorClicked(QUrl)));
    setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);

    document()->setDefaultStyleSheet(" \
        a {text-decoration: none; font-weight: bold;} \
        p {white-space: nowrap;} \
        .error {color: red;} \
        .bold {font-weight: bold;} \
        .error a { color: red;} \
    ");
    _timer->setInterval(100);
    connect(_timer, SIGNAL(timeout()), SLOT(onTimer()));
    _timer->start();
}

void Console::addLine(const QString & line)
{
    appendLine(prepare(line) % "<br>");
}

void Console::addLine(const QString & line, const QString & cls)
{
    appendLine("<span class='" % cls % "'>" % prepare(line) % "</span><br>");
}

void Console::appendLine(const QString & line)
{
    _buffer.append(line);
    //insertHtml(line);
}

void Console::onTimer()
{
    if (_buffer.length()){
        moveCursor(QTextCursor::End);
        insertHtml(_buffer.join(""));
        _buffer.clear();
        moveCursor(QTextCursor::End);
    }
}

QString Console::prepare(const QString & line)
{
    QString printLine = line;
    printLine = printLine.replace("<", "&lt;").replace(">", "&gt;");
    QRegExp rx(".*File \"(.+)?\", line (\\d+).*");
    int pos = 0;
    if ((pos = rx.indexIn(printLine, pos)) != -1 ){
        QString file = rx.cap(1);
        QString line = rx.cap(2);
        printLine = printLine.replace(file, "<a href='" % (file.startsWith('/') ? file : _rootPath % QDir::separator() % file) % ":" % line % "'>" % file % "</a>");
    }
    printLine = printLine.replace(QRegExp("\\s{4}"), "&nbsp;&nbsp;&nbsp;");
    return printLine;
}

void Console::setRoot(const QString & path)
{
    _rootPath = path;
}

void Console::onAnchorClicked(const QUrl & url)
{
    QStringList file = url.path().split(":");
    emit fileNavigate(file[0], file[1].toInt());
}

void Console::clearConsole()
{
    clear();
}
